package com.qsl.system.fillter;

import com.alibaba.fastjson.JSON;
import com.qsl.common.result.Result;
import com.qsl.common.result.ResultCodeEnum;
import com.qsl.common.util.JwtHelper;
import com.qsl.common.util.ResponseUtil;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 认证解析过滤器-token    // 自定义过滤器:OncePerRequestFilter
 */
@AllArgsConstructor // 所有参数构造器   ==> Redis
@NoArgsConstructor // 无参构造器
public class TokenAuthenticationFilter extends OncePerRequestFilter {

    //    Redis
    private RedisTemplate redisTemplate;

    /**
     * 放行登录接口
     *
     * @param req
     * @param resp
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws ServletException, IOException {

        //  控制台输出日志，请求头路径
        logger.info("==> uri:" + req.getRequestURI());
        //放行所拦截的登录接口路径
        if ("/admin/system/index/login".equals(req.getRequestURI())) {
            chain.doFilter(req, resp);
            return;
        }

        UsernamePasswordAuthenticationToken authentication = getAuthentication(req);

        if (authentication != null) {
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // 放行
            chain.doFilter(req, resp);
        } else {
            ResponseUtil.out(resp, Result.build(null, ResultCodeEnum.PERMISSION));
        }
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req) {
        // token放在header里
        String token = req.getHeader("token");
        //   自定义日志
        logger.info("=====>loken:" + token);
        if (!StringUtils.isEmpty(token)) {
            String username = JwtHelper.getUsername(token);
            // 从Redis获取数据
            String authoritiesString = (String) redisTemplate.opsForValue().get(username);
            logger.info("=====>Redis:" + authoritiesString);
            // 将JSON字符串转为Java对象
            List<Map> mapList = JSON.parseArray(authoritiesString, Map.class);
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
            for (Map map : mapList) {
                authorities.add(new SimpleGrantedAuthority((String) map.get("authority")));
            }
            return new UsernamePasswordAuthenticationToken(username, null, authorities);
        }
        return null;
    }


}
